home *** CD-ROM | disk | FTP | other *** search
/ ETO Development Tools 1 / ETO Development Tools 1.iso / Essentials / MacApp Documentation / MacApp AppleLink Messages / MacApp.Tech$ May 89 / U0001-UAsynchS < prev    next >
Encoding:
Text File  |  1989-04-25  |  3.5 KB  |  152 lines  |  [TEXT/MPS ]

  1. (*
  2. A simple unit that demonstrates how to produce asynchronous sound with
  3. the Macintosh Sound Manager.  Although I am pretty confident about this code,
  4. I don't guarantee that this code demonstrates the correct way to do things.  It
  5. does seem to work reliably.
  6.  
  7. This unit doesn't solve any of the tricky issues about using the Sound Manager.
  8. Primarily, sound channels should be disposed of as soon as they are no longer
  9. needed.  This code does just that, but it doesn't prevent your program or a
  10. background program from trying to make sound.
  11.  
  12. Changes:
  13.  
  14. 2/16/89  Lock the sound resource; state restored in call back;
  15.             gSoundPlaying is the actual handle.
  16. 3/24/89     IsSoundPlaying disposes of the channel when done.
  17.  
  18. Larry Rosenstein
  19. Apple Computer, Inc.
  20.  
  21. © Copyright 1988, 1989 Apple Computer Inc.  All Rights Reserved.
  22. *)
  23.  
  24.  
  25. UNIT UAsynchSnd;
  26.  
  27. INTERFACE
  28.  
  29. USES
  30.     MemTypes, Quickdraw, OSIntf, ToolIntf;
  31.     
  32.     { call this before any other routine }
  33. PROCEDURE InitUAsynchSnd;
  34.  
  35.     { returns TRUE if an asynchronous sound is playing }
  36. FUNCTION  IsSoundPlaying: BOOLEAN;
  37.  
  38.     { equivalent to SndPlay, but does it asynchronously; if you call this
  39.         while another sound is playing, the first one will be stopped }
  40. FUNCTION  AsynchSndPlay(sndHandle: Handle): OSErr;
  41.  
  42.     { stop the sound from playing; may be called even if no sound is
  43.         currently playing }
  44. PROCEDURE StopAsynchSound;
  45.  
  46.     { should be called when your program exits }
  47. PROCEDURE TerminateUAsynchSnd;
  48.  
  49. IMPLEMENTATION
  50.  
  51. VAR
  52.     gSoundPlaying:        Handle;
  53.     gSoundState:        SignedByte;
  54.     gSndChannel:        SndChannelPtr;
  55.     
  56.     PROCEDURE ChanCallBack(chan: SndChannelPtr; cmd: SndCommand); FORWARD;
  57.     FUNCTION  GetA5: LONGINT; INLINE $2E8D; {MOVE.L A5,(A7)}
  58.     FUNCTION  LoadA5(newA5: LONGINT): LONGINT;
  59.                         INLINE $2F4D,$0004,$2A5F;
  60.     
  61. (********************)
  62.  
  63. PROCEDURE InitUAsynchSnd;
  64. BEGIN
  65.     gSndChannel := NIL;
  66.     gSoundPlaying := NIL;
  67. END;
  68.     
  69.  
  70. FUNCTION  AsynchSndPlay(sndHandle: Handle): OSErr;
  71.     VAR    err:            OSErr;
  72.         aCommand:        SndCommand;
  73.         
  74. BEGIN
  75.     StopAsynchSound;    { kill the current sound & channel }
  76.     
  77.     err := noErr; { default value }
  78.     
  79.     { gSndChannel should be NIL now }
  80.     err := SndNewChannel(gSndChannel, 0, 0, @ChanCallBack);
  81.             { We don't specify a synthesizer, since we are assuming that
  82.                 the snd resource specifies one.  For example, the
  83.                 standard Clink-Klank snd resource doesn't use the 
  84.                 sampled synthesizer. }
  85.     
  86.     gSoundState := HGetState(sndHandle);
  87.     MoveHHi(sndHandle);
  88.     HLock(sndHandle);
  89.     gSoundPlaying := sndHandle;
  90.     
  91.     IF err = noErr THEN
  92.         err := SndPlay(gSndChannel, sndHandle, TRUE);
  93.     
  94.     WITH aCommand DO BEGIN
  95.         cmd := callBackCmd;
  96.         param1 := 0;
  97.         param2 := GetA5;
  98.         END;
  99.     IF err = noErr THEN
  100.         err := SndDoCommand(gSndChannel, aCommand, FALSE);
  101.         
  102.     IF err <> noErr THEN
  103.         StopAsynchSound;        { flush channel; unlock sound }
  104.     
  105.     AsynchSndPlay := err;
  106. END;
  107.  
  108.  
  109. PROCEDURE ChanCallBack(chan: SndChannelPtr; cmd: SndCommand);
  110.     VAR    oldA5:    LONGINT;
  111. BEGIN
  112.     oldA5 := LoadA5(cmd.param2);    { get the application's A5 and set it }
  113.     
  114.     HSetState(gSoundPlaying, gSoundState);
  115.     gSoundPlaying := NIL;
  116.     
  117.     oldA5 := LoadA5(oldA5);            { restore old A5 }
  118. END;
  119.  
  120.  
  121. FUNCTION  IsSoundPlaying: BOOLEAN;
  122.     VAR    result: BOOLEAN;
  123.     
  124. BEGIN
  125.     result := gSoundPlaying <> NIL;
  126.     IF NOT result then
  127.         StopAsynchSound;  { to dispose of channel }
  128.     IsSoundPlaying := result;
  129. END;
  130.  
  131.  
  132. PROCEDURE StopAsynchSound;
  133. BEGIN
  134.     IF gSndChannel <> NIL THEN BEGIN
  135.         IF SndDisposeChannel(gSndChannel, TRUE) = noErr THEN { nothing };
  136.         gSndChannel := NIL;
  137.         END;
  138.     IF gSoundPlaying <> NIL THEN
  139.     BEGIN
  140.         HSetState(gSoundPlaying, gSoundState);
  141.         gSoundPlaying := NIL;
  142.     END;
  143. END;
  144.  
  145. PROCEDURE TerminateUAsynchSnd;
  146. BEGIN
  147.     StopAsynchSound;
  148. END;
  149.  
  150.  
  151. END.
  152.